package com.motu.monstercity.server.game.logichandler;

import com.google.protobuf.InvalidProtocolBufferException;
import com.motu.monstercity.module.common.network.RequestParam;
import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.CsGameCave.*;
import com.motu.monstercity.server.game.base.AllParam;
import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.base.LockKey;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.bag.ItemId;
import com.motu.monstercity.server.game.commondata.build.BuildConstant;
import com.motu.monstercity.server.game.commondata.cave.CaveMain;
import com.motu.monstercity.server.game.commondata.maintask.MainTaskConstant;
import com.motu.monstercity.server.game.commondata.skill.SkillConstant;
import com.motu.monstercity.server.game.log.LogType;
import com.motu.monstercity.server.game.logic.*;
import com.motu.monstercity.server.game.userdata.*;
import com.motu.vertx.module.utility.main.MainService;
import com.motu.vertx.module.utility.toolset.ErrorWord;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.shareddata.Lock;
import org.checkerframework.checker.units.qual.C;

import java.util.List;

public class CaveHandler {
    // CMD_GAME_CAVE_MAIN_INFO = 73101; // 怪兽洞窟的用户数据 [1]第一次请求
    public static Object CMD_GAME_CAVE_MAIN_INFO(RequestParam clientParam) throws Exception {
        CSGameCaveMainInfoRequest request = CSGameCaveMainInfoRequest.parseFrom(clientParam.getData());
        CSGameCaveMainInfoResponse.Builder response = CSGameCaveMainInfoResponse.newBuilder();
        long userId = clientParam.getUserId();

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserCaveInfo userCaveInfo = CaveManager.getUserCaveInfo(userId);
        ProtoDataUtils.updatePBUserData(pbUserData, userCaveInfo, true);
        UserCaveLocation userCaveLocation = CaveManager.getUserCaveLocation(userId);
        ProtoDataUtils.updatePBUserData(pbUserData, userCaveLocation, true);
        for (UserCaveRecord userCaveRecord : CaveManager.getUserCaveRecordList(userId)) {
            ProtoDataUtils.updatePBUserData(pbUserData, userCaveRecord, true);
        }

        List<UserBuild> userBuilds = BuildManager.getUserBuildListByType(userId, BuildConstant.BUILD_TYPE_2);// 商业类建筑的加成会变化，下发给客户端
        for (UserBuild userBuild : userBuilds) {
            ProtoDataUtils.updatePBUserData(pbUserData, userBuild, true);
        }

        return response;
    }

    // CMD_GAME_CAVE_ENEMY_LIST = 73102; // 匹配到的对手列表 [2]每次打开请求
    public static Object CMD_GAME_CAVE_ENEMY_LIST(RequestParam clientParam) throws Exception {
        CSGameCaveEnemyListRequest request = CSGameCaveEnemyListRequest.parseFrom(clientParam.getData());
        CSGameCaveEnemyListResponse.Builder response = CSGameCaveEnemyListResponse.newBuilder();
        long userId = clientParam.getUserId();

        // 执行逻辑
        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserCaveLocation userCaveLocation = CaveManager.getUserCaveLocation(userId);
        CaveMain caveMain = CaveManager.getCaveMain(userCaveLocation.getAreaType(), userCaveLocation.getFloorId());
        List<PBCaveEnemy.Builder> list = CaveManager.getCaveEnemyList(caveMain, userInfo.getServerId());
        for (PBCaveEnemy.Builder builder : list) {
            response.addEnemyList(builder);
        }
        ProtoDataUtils.updatePBUserData(response.getUserBuilder(), userCaveLocation, true);


        return response;
    }

    // CMD_GAME_CAVE_FIGHT = 73103; // 进行挑战
    public static Object CMD_GAME_CAVE_FIGHT(RequestParam clientParam) throws Exception {
        CSGameCaveFightRequest request = CSGameCaveFightRequest.parseFrom(clientParam.getData());
        CSGameCaveFightResponse.Builder response = CSGameCaveFightResponse.newBuilder();
        long userId = clientParam.getUserId();

        long enemyId = request.getUid();//对手的userid
        CaveMain caveMainMy = CaveManager.getCaveMain(request.getCaveMainIdMy());
        CaveMain caveMainTarget = CaveManager.getCaveMain(request.getCaveMainIdTarget());// 没有这个坑位
        if (caveMainMy == null || caveMainTarget == null) {
            return ErrorWord.NOT_DATA;
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserPower userPower = GameUser.getUserPower(userId);
        long userCurPower = GameUser.countTotalPowerModule(userId, userPower, SkillConstant.EFFECT_TYPE_4, 0);// 实际总战力
        UserInfo userInfo = GameUser.getUserInfo(userId);
        int serverId = userInfo.getServerId();
        UserCaveInfo userCaveInfo = CaveManager.getUserCaveInfo(userId);
        UserCaveLocation userCaveLocation = null;
        boolean isSucc = false;
        if (caveMainTarget.isPVEServer()) {// pve 不需要加锁，直接打，1-4层
            userCaveLocation = CaveManager.getUserCaveLocation(userId);
            if (userCaveLocation.getAreaType() != caveMainMy.getAreaType() || userCaveLocation.getFloorId() != caveMainMy.getFloorId()) {
                return ErrorWord.REPEATED_OPERATION;// 我的实际位置跟客户端上传的不一致，发生变化了
            }
            if (!CaveManager.checkEnemyPVE(caveMainMy, caveMainTarget)) {
                return ErrorWord.WRONG_STATUS;// 校验对手是否能打
            }
            if (userCurPower > caveMainTarget.getMonsterPower()) {
                isSucc = true;
                CaveManager.handlePVESucc(pbUserData, userInfo, userPower, userCurPower, userCaveLocation, userCaveInfo, caveMainTarget);
            }
        } else {// pvp，
            if (CaveManager.isLockServer(caveMainMy)) {// 按服加锁, 我在4区域第一名，或是5区域的底部5名，或是5区域的第1名，或是6区域的底部5名时，需要全服加锁
                Lock lockServer = null;
                try {
                    lockServer = MainService.getVertLock(LockKey.getCaveLock(serverId));
                    userCaveLocation = CaveManager.getUserCaveLocation(userId);
                    if (userCaveLocation.getAreaType() != caveMainMy.getAreaType() || userCaveLocation.getFloorId() != caveMainMy.getFloorId()) {
                        return ErrorWord.REPEATED_OPERATION;// 我的实际位置跟客户端上传的不一致，发生变化了
                    }
                    ServerCaveLocation serverCaveLocationTarget = CaveManager.getServerCaveLocation(serverId, caveMainTarget.getCaveKey());
                    if (!CaveManager.checkEnemyPVP(caveMainMy, caveMainTarget, serverCaveLocationTarget, enemyId)) {
                        return ErrorWord.WRONG_STATUS;// 校验对手是否能打,对方排名已经变化，不能打
                    }
                    if (userCurPower > CaveManager.getEnemyPower(caveMainTarget, serverCaveLocationTarget)) {// 胜利
                        isSucc = true;
                        CaveManager.handlePVPSucc(pbUserData, userInfo, userCaveLocation, userPower, userCurPower, caveMainMy, caveMainTarget, serverCaveLocationTarget, enemyId);
                    }
                } catch (InvalidProtocolBufferException e) {
                    return ErrorWord.PROTOCOL_PARSE_FAILED;
                } finally {// 释放锁
                    MainService.releaseVertLock(lockServer);
                }
            } else {// 同区域挑战，按区域加锁
                Lock lockArea = null;
                try {
                    lockArea = MainService.getVertLock(LockKey.getCaveLockArea(serverId, caveMainMy.getAreaType()));
                    userCaveLocation = CaveManager.getUserCaveLocation(userId);
                    if (userCaveLocation.getAreaType() != caveMainMy.getAreaType() || userCaveLocation.getFloorId() != caveMainMy.getFloorId()) {
                        return ErrorWord.REPEATED_OPERATION;// 我的实际位置跟客户端上传的不一致，发生变化了
                    }
                    ServerCaveLocation serverCaveLocationTarget = CaveManager.getServerCaveLocation(serverId, caveMainTarget.getCaveKey());
                    if (!CaveManager.checkEnemyPVP(caveMainMy, caveMainTarget, serverCaveLocationTarget, enemyId)) {
                        return ErrorWord.WRONG_STATUS;// 校验对手是否能打,对方排名已经变化，不能打
                    }
                    if (userCurPower > CaveManager.getEnemyPower(caveMainTarget, serverCaveLocationTarget)) {// 胜利
                        isSucc = true;
                        CaveManager.handlePVPSucc(pbUserData, userInfo, userCaveLocation, userPower, userCurPower, caveMainMy, caveMainTarget, serverCaveLocationTarget, enemyId);
                    }
                } catch (InvalidProtocolBufferException e) {
                    return ErrorWord.PROTOCOL_PARSE_FAILED;
                } finally {// 释放锁
                    MainService.releaseVertLock(lockArea);
                }
            }
        }

        response.setIsSucc(isSucc);
        if (isSucc) {// 挑战成功，下发新的对手列表
            CaveManager.sendOnceReward(pbUserData, userInfo, userCaveInfo, caveMainTarget, userCurPower);// 发放首次达层奖励
            CaveManager.updateCaveRank(serverId, userId, caveMainTarget);// 更新我的榜单
            CaveManager.updateEarn(pbUserData, userInfo, userPower, userCaveLocation);// 根据坑位更新城市收益的加成
            MainTaskManager.updateUserHonor(pbUserData, userInfo, MainTaskConstant.HONOR_TYPE_103, caveMainTarget.getAreaType(), false);// 全量更新
            for (PBCaveEnemy.Builder builder : CaveManager.getCaveEnemyList(caveMainTarget, serverId)) {
                response.addEnemyList(builder);
            }
            MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_154, userCaveLocation.getFloorId(), userCaveLocation.getAreaType());// 更新主线任务,成就,日常任务的进度
            MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_156, 1);// 更新主线任务,成就,日常任务的进度
        } else if (enemyId > 0) {// 我方输了，对手生成胜利的战报
            CaveManager.createCaveRecord(enemyId, userInfo.getId(), userInfo.getUserName(), 0, caveMainTarget.getAreaType(), caveMainTarget.getFloorId(), caveMainTarget.getFloorId());
        }
        return response;
    }


    // CMD_GAME_CAVE_GET_SECOND_REWARD = 73104; // 领取每秒奖励
    public static Object CMD_GAME_CAVE_GET_SECOND_REWARD(RequestParam clientParam) throws Exception {
        CSGameCaveGetSecondRewardRequest request = CSGameCaveGetSecondRewardRequest.parseFrom(clientParam.getData());
        CSGameCaveGetSecondRewardResponse.Builder response = CSGameCaveGetSecondRewardResponse.newBuilder();
        long userId = clientParam.getUserId();

        // 执行逻辑
        UserCaveInfo userCaveInfo = CaveManager.getUserCaveInfo(userId);
        UserCaveLocation userCaveLocation = CaveManager.getUserCaveLocation(userId);
        CaveMain caveMain = CaveManager.getCaveMain(userCaveLocation.getAreaType(), userCaveLocation.getFloorId());
        if (caveMain == null || caveMain.getSecondReward() == 0) {
            return ErrorWord.NOT_DATA;
        }

        long curTime = TimeUtils.getCurTime();
        long diffTime = curTime - userCaveInfo.getSecondRewardTime();
        if (diffTime < AllParam.CAVE_SECOND_REWARD_LIMIT[0]) {
            return ErrorWord.STILL_IN_CDTIME;//  间隔时间不足900秒
        }

        if (diffTime > AllParam.CAVE_SECOND_REWARD_LIMIT[1]) {
            diffTime = AllParam.CAVE_SECOND_REWARD_LIMIT[1];// 不能超过上限
        }

        UserInfo userInfo = GameUser.getUserInfo(userId);
        PBUserData.Builder pbUserData = response.getUserBuilder();

        double num = caveMain.getSecondReward();
        num = num * diffTime / 10000;// 配置有放大1W倍

        RewardManager.addReward(userInfo, ItemId.TYPE_IAP_CAVE_ITEM, (long)num, pbUserData, LogType.CAVE_SECONDE_REWARD);
        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_157, (int)num);// 更新主线任务,成就,日常任务的进度

        userCaveInfo.putSecondRewardTime(curTime);
        userCaveInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userCaveInfo);

        return response;
    }


    // CMD_GAME_CAVE_RECORD_LIST = 73105; // 战报的记录[3]每次打开请求增量下发
    public static Object CMD_GAME_CAVE_RECORD_LIST(RequestParam clientParam) throws Exception {
        CSGameCaveRecordListRequest request = CSGameCaveRecordListRequest.parseFrom(clientParam.getData());
        CSGameCaveRecordListResponse.Builder response = CSGameCaveRecordListResponse.newBuilder();
        long userId = clientParam.getUserId();
        long dbid = request.getDbid();

        PBUserData.Builder pbUserData = response.getUserBuilder();
        List<UserCaveRecord> list = CaveManager.getUserCaveRecordList(userId);
        for (UserCaveRecord userCaveRecord : list)  {
            if (userCaveRecord.getId() > dbid)  {
                ProtoDataUtils.updatePBUserData(pbUserData, userCaveRecord, true);
            }
        }
        return response;
    }
}
